/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.svh.Servicios;

import com.svh.Dao.Impl.MarcaDaoImpl;
import com.svh.Dao.Impl.ProductoDaoImpl;
import com.svh.Dao.Impl.SubTipoProductoMarcaDaoImpl;
import com.svh.Dao.MarcaDao;
import com.svh.Dao.ProductoDao;
import com.svh.Dao.SubTipoProductoMarcaDao;
import com.svh.Entidad.Marca;
import com.svh.Entidad.Producto;
import com.svh.Entidad.SubtipoProductoMarca;
import com.svh.Hibernate.HibernateConexion;
import com.svh.Utils.IConexion;
import com.svh.Utils.Utilitario;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 *
 * @author David
 */
public class MigrarServicios {

    private InputStream inputStream;
    
    private int idUsuario;

    private final SubTipoProductoMarcaDao daoSubTipoProductoMarca;

    private final MarcaDao daoMarca;

    private final ProductoDao daoProducto;

    private final IConexion conexion;

    public MigrarServicios(int idUsuario) {
        this.idUsuario = idUsuario;
        conexion = new HibernateConexion();
        daoSubTipoProductoMarca = new SubTipoProductoMarcaDaoImpl(conexion);
        daoMarca = new MarcaDaoImpl(conexion);
        daoProducto = new ProductoDaoImpl(conexion);
    }

    public void migrar(String nombre) {
        String extension = nombre.substring(nombre.lastIndexOf(".") + 1, nombre.length());
        List sheetData = new ArrayList();
        if (extension.compareTo("xlsx") == 0) {
            sheetData = leerExcelXLSX();
        } else {
            sheetData = leerExcelXLS();
        }
        if (sheetData.size() > 0) {
            migrarDatos(sheetData);
        }
    }

    private List leerExcelXLS() {
        List sheetData = new ArrayList();
        try {
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            HSSFSheet sheet = workbook.getSheetAt(0);
            Iterator rows = sheet.rowIterator();
            while (rows.hasNext()) {
                HSSFRow row = (HSSFRow) rows.next();
                Iterator cells = row.cellIterator();
                List data = new ArrayList();
                while (cells.hasNext()) {
                    HSSFCell cell = (HSSFCell) cells.next();
                    data.add(cell);
                }
                sheetData.add(data);
            }
            return sheetData;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private List leerExcelXLSX() {
        List sheetData = new ArrayList();
        try {
            XSSFWorkbook wb = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = wb.getSheetAt(0);
            Iterator<Row> rows = sheet.rowIterator();
            Row row;
            Cell cell;
            while (rows.hasNext()) {
                row = rows.next();
                Iterator<Cell> cellIterator = row.cellIterator();
                List data = new ArrayList();
                while (cellIterator.hasNext()) {
                    cell = cellIterator.next();
                    data.add(cell);
                }
                sheetData.add(data);
            }
            return sheetData;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private void migrarDatos(List sheetData) {
        List<SubtipoProductoMarca> insert = new ArrayList();
        List<SubtipoProductoMarca> update = new ArrayList();
        if (validarExcel((List) sheetData.get(0))) {
            for (int i = 1; i < sheetData.size(); i++) {
                List list = (List) sheetData.get(i);
                validarDatos(insert, update, list);                
            }
            ingresarActualizarDatos(insert, update);
            Utilitario.enviarMensajeGlobalValido("Se migraron los datos");
        } else {
            Utilitario.enviarMensajeGlobalError("Error Formato de Excel no Valido");
        }
    }

    private void ingresarActualizarDatos(List<SubtipoProductoMarca> insert, List<SubtipoProductoMarca> update) {
        ////// INSERTAR ///////
        if (insert.size() > 0) {
            conexion.beginTransaccion();
            for (SubtipoProductoMarca ins : insert) {
                ins.setIdUsuario(idUsuario);
                daoSubTipoProductoMarca.agregar(ins);
            }
            conexion.closeTransaccion();
        }
        ////// UPDATE ///////
        if (update.size() > 0) {
            conexion.beginTransaccion();
            for (SubtipoProductoMarca upd : update) {
                upd.setIdUsuario(idUsuario);
                daoSubTipoProductoMarca.actualizar(upd);
            }
            conexion.closeTransaccion();
        }
    }

    public void validarDatos(List<SubtipoProductoMarca> insert, List<SubtipoProductoMarca> update, List dato) {
        if (!validarDatos(dato)) {
            return;
        }
        SubtipoProductoMarca aux = obtenerSubtipoProductoMarca(dato.get(0).toString());
        if (aux != null) {////// EXISTE EL SUBTIPO
            String precio = "";
            if (dato.size() == 5) {
                precio = dato.get(4).toString();
            } else {
                precio = dato.get(3).toString();
            }
            if (aux.getPrecio() != Double.parseDouble(precio)) {
                aux.setPrecio(Double.parseDouble(dato.get(4).toString()));
                update.add(aux);
            }
        } else {////// NO EXISTE EL SUBTIPO
            aux = new SubtipoProductoMarca();
            aux.setCodigo(dato.get(0).toString());
            //// PRODUCTO ////
            Producto prod = obtenerProducto(dato.get(1).toString());
            if (prod == null) {
                prod = new Producto();
                prod.setNombre(dato.get(1).toString());
                prod.setDescripcion("Descripcion no disponible");
                registrarProducto(prod);
            }

            aux.setProducto(prod);
            //// MARCA ////
            Marca marca = obtenerMarca(dato.get(2).toString());
            if (marca == null) {
                marca = new Marca();
                marca.setNombre(dato.get(2).toString());
                marca.setDescripcion("Descripcion no disponible");
                registrarMarca(marca);
            }
            aux.setMarca(marca);
            if (dato.size() == 5) {
                aux.setDescripcion(dato.get(3).toString());
                aux.setPrecio(Double.parseDouble(dato.get(4).toString()));
            } else {
                aux.setPrecio(Double.parseDouble(dato.get(3).toString()));
            }
            insert.add(aux);
        }
    }

    private boolean validarDatos(List dato) {
        if (dato == null || dato.size() > 5 || dato.size() < 4) {
            return false;
        }
        for (int i = 0; i < dato.size(); i++) {
            if (Utilitario.esNulo(dato.get(i).toString())) {
                return false;
            }
        }
        String precio = "";
        if (dato.size() == 5) {
            precio = dato.get(4).toString();
        } else {
            precio = dato.get(3).toString();
        }
        return !Utilitario.esSoloDecimalPositivo(precio);
    }

    private boolean validarExcel(List list) {
        String vec[] = {"COD", "PROD", "MARC", "SUBCOD", "PRECIO"};
        for (int i = 0; i < vec.length; i++) {
            if (vec[i].compareTo(list.get(i).toString()) != 0) {
                return false;
            }
        }
        return true;
    }

    public SubtipoProductoMarca obtenerSubtipoProductoMarca(String codigo) {
        conexion.beginConexion();
        SubtipoProductoMarca aux = daoSubTipoProductoMarca.getSubtipoProductoMarcaPorCod(codigo);
        conexion.closeConexion();
        return aux;
    }

    public Marca obtenerMarca(String nombre) {
        conexion.beginConexion();
        Marca aux = daoMarca.getMarcaPorNombre(nombre);
        return aux;
    }

    public Producto obtenerProducto(String nombre) {
        conexion.beginConexion();
        Producto aux = daoProducto.getProductoPorNombre(nombre);
        return aux;
    }

    public void registrarProducto(Producto producto) {
        conexion.beginTransaccion();
        daoProducto.agregar(producto);
        conexion.closeTransaccion();
    }

    public void registrarMarca(Marca marca) {
        conexion.beginTransaccion();
        daoMarca.agregar(marca);
        conexion.closeTransaccion();
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public int getIdUsuario() {
        return idUsuario;
    }

    public void setIdUsuario(int idUsuario) {
        this.idUsuario = idUsuario;
    }
}
